home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Amiga
/
World of Amiga.iso
/
archive
/
assembly
/
plasmabb.lha
/
PlasmaBB.s
< prev
Wrap
Text File
|
1992-12-26
|
12KB
|
381 lines
***********************************************************
* © 1992, Dancing Fool of Epsilon
*
* Using AsmOne, to make into executable:
* 1. Make sure that BOOT_BLOCK is EQU'ed to 0.
* 2. >a
* 3. >wo miniplasma
*
* Using AsmOne, to put on boot block:
* 1. Make sure that BOOT_BLOCK is EQU'ed to 1.
* 2. >a
* 3. >ws
* 4. RAM_PTR> Start
* 5. DISK_PTR> 0
* 6. LENGTH> 2
* 7. >cc
*
***********************************************************
* Why did I write this?
*
* Well, after spending several months trying to figure rgb plasma out (and
* finally getting it!), I got some source to an old Masters demo that had
* some zero bit plane plasma in it that looked a lot like this, only not
* as good, so I decided to make a boot block out of it. After that, I
* decided to put the source out for the world to see, learn from, and laugh
* at.
*
* How does it work?
*
* This code is pretty much the same a any other plasma that uses bit planes.
* Zero bit plane plasma is a little bit different (and a lot faster), but looks
* crappy, so who cares? :^) Anyway, I set up four bit planes of the same bit
* map just a different offsets and scroll values. Bit plane one is +4 into
* the bit map and has a scroll of 4, bit plane two is +6 and scroll of $c,
* bit plane 3 is +6 and scroll $c, and bit plane three is +8 and scroll of 4.
* Each frame you bit in a sine wave on the bit map "stripes". Looking
* at this data shows that on any given scan line you will end up with the
* following bit patterns:
*
* bpl1 $00ff00ffff00ff0000ff00ffff00ff0000ff00ffff00ff0000ff00ffff00ff00
* bpl2 $ 00ffff00ff0000ff00ffff00ff0000ff00ffff00ff0000ff00ffff00ff0000ff
* bpl3 $00ffff00ff0000ff00ffff00ff0000ff00ffff00ff0000ff00ffff00ff0000ff
* bpl4 $ ff00ff0000ff00ffff00ff0000ff00ffff00ff0000ff00ffff00ff0000ff00ff
*
* Across the scan line the color pattern is:
*
* color 13 6 11 5 2 9 4 10 13 6 11 5 2 9 4 10 13 6 11 5 2 9 4 10 ...
*
* So, even with four bitplanes only eight colors ever occour. With this
* in mind, and knowing the maximum number of copper cycles per scan line,
* we know that these colors will repeat six times per raster.
*
* In standard plasma, which this is not, you would take the next value
* from your sine table and use that as an offset into your color bar. Then,
* you blit your color bar into the first "column" of your copper list, and
* repeat for the other fourty-seven (a column is a color entry). To do rgb
* plasma you would use all three blitter sources, one for each color component,
* and or them all together to obtain the correct values for your copper list.
*
* This plasma is a little bit different. Instead of using a horizontal sine
* wave on my copper bars, I use a vertical sine wave. This allows me to blit
* an entire raster at a time. This is a little different approach from
* normal plasma, but it also takes less static space, which allows it to
* easily fit on a boot block.
*
* Do what ever you want with this source, just don't take credit for it!
* Contact me at (on InterNet):
* idr@rigel.cs.pdx.edu
* Contact Epsilon at:
* Epsilon
* P.O.B. 1914
* Beaverton, OR 97075-1914
* U.S.A.
***********************************************************
* Equates
***********************************************************
BOOT_BLOCK EQU 0 ; 0 = normal executable, 1 = boot block
CUSTOM EQU $dff000 ; custom chip base
CIA_A EQU $bfe001 ; cia chip for left mouse button
S_SPEED EQU (2<<1) ; speed to 'scroll' copper(must be a mult of 2)
S_SIZE EQU 72 ; max scroll. if you change the color data,
; then you may need to change this too.
ROWS EQU 180 ; number of plasma rasters (changeable)
COLS EQU 6 ; number of columns. should be 6, but could
; be less.
COLORS EQU 8 ; number of color combinations that occour.
MOD EQU 2 ; size of 'move' instruction in copper list
AMP EQU $20 ; amplitude of sine data. if you change the
; sine data, you should change this.
MD2 EQU (4*((COLS*COLORS)+1)) ; size of one raster of
; clist data
SIZE EQU ((64*COLS*COLORS)+1) ; blit size for copper list
***********************************************************
* Macros
***********************************************************
WaitBlit MACRO
tst.b (a5) ; ignore first test for old Agnus
.\@ btst #6,(a5) ; test blit done bit in high byte of
; DMACON
bne.b .\@ ; loop if not done
ENDM
WaitVblank MACRO
.\@ move.l 4-2(a5),d0 ; read full beam position
andi.l #$0003ff00,d0 ; mask of hoizontal position
cmpi.l #$00002c00,d0 ; top of screen?
bne.b .\@ ; not yet.
ENDM
*********************************************************************
IFNE BOOT_BLOCK
Start: dc.b "DOS",0 ; boot block id long work
dc.l 0 ; checksum
dc.l $370 ; root block
ELSE
section plasma_bb,code_c
ENDIF
TakeSystem:
movem.l d1-d7/a1-a6,-(sp)
IFEQ BOOT_BLOCK
movea.l 4.w,a6 ; at boot this is already done!
ENDIF
move.l #(size_of_list),d0
move.l #($10003),d1 ; MEMF_CHIP | MEMF_PUBLIC | MEMF_CLEAR
jsr -198(a6) ; AllocMem()
tst.l d0 ; did we get the mem?
beq.w err_exit ; nope.
move.l d0,a6 ; ptr to mem.
lea sine(pc),a0 ; sine table
move.l a0,sineptr(a6) ; initial sine ptr
move.l #CUSTOM+2,a5 ; Custom chip base + 2!!!
move.w (a5),d0 ; Save DMACON
ori.w #$8000,d0 ; OR in the SET bit for later
move.l a6,a0
move.w d0,(a0) ; Keep it
move.w #$83c0,$96-2(a5); Turn on only certain DMA channels
move.w #$0020,$96-2(a5); kill sprite DMA
InstallPlasmaCopper:
lea Copper1(a6),a0 ; pointer to our copper list
move.l a0,$80-2(a5) ; install it
move.w #$00e0,d0 ; bpl1pth
moveq #7,d1 ; loop counter
.make_bplpt: move.w d0,(a0)+ ; write it to our copper list
addq.w #2,a0 ; next in list
addq.w #2,d0 ; next value
dbra d1,.make_bplpt ; loop
sub.w #30,a0 ; a0 points to mapptrs + 2
move.l a6,d0 ; data segment
add.l #PBmap+4,d0 ; plasma map plus a bit
move.w d0,4(a0) ; bpl1ptl
swap d0 ; high word in low half of register
move.w d0,(a0) ; bpl1pth
swap d0 ; swap back
addq.l #2,d0 ; in a bit more
move.w d0,12(a0) ; bpl2ptl
move.w d0,20(a0) ; bpl3ptl
swap d0 ; high word in low word
move.w d0,8(a0) ; bpl2pth
move.w d0,16(a0) ; bpl3pth
swap d0 ; swap back
addq.l #2,d0 ; in some more
move.w d0,28(a0) ; bpl4ptl
swap d0 ; guess why I do this. :^)
move.w d0,24(a0) ; bpl4pth
lea plasma_copper1(a6),a0 ; raster data
move.l #$2d1ffffe,d1 ; starting raster - 1
move.w #ROWS-1,d5 ; number of rasters
m_plasma1: add.l #$01000000,d1 ; next raster
move.l d1,(a0)+ ; write raster wait to clist
moveq #COLS-1,d4 ; number of columns
m_plasma2: move.w #$019a,(a0)+ ; write each color out to clist
addq.w #2,a0 ; next entry
move.w #$018c,(a0)+
addq.w #2,a0
move.w #$0196,(a0)+
addq.w #2,a0
move.w #$018a,(a0)+
addq.w #2,a0
move.w #$0184,(a0)+
addq.w #2,a0
move.w #$0192,(a0)+
addq.w #2,a0
move.w #$0188,(a0)+
addq.w #2,a0
move.w #$0194,(a0)+
addq.w #2,a0
dbra d4,m_plasma2 ; loop for columns
dbra d5,m_plasma1 ; loop for rasters
moveq #-2,d0 ; end of clist
move.l d0,(a0) ; write it out
moveq #0,d4
; the following are not in the clist to save space
move.w #$4200,$100-2(a5) ; bplcon0 (4 bit planes)
move.w #$00c4,$102-2(a5) ; fine scroll
moveq #$0008,d0 ; modulo value
move.w d0,$0108-2(a5) ; write to clist
move.w d0,$010a-2(a5) ; ...
move.w #$2e78,$8e-2(a5) ; window start
move.w #$e2c6,$90-2(a5) ; window stop
move.w #$0028,$92-2(a5) ; data fetch start
move.w #$00d8,$94-2(a5) ; data fetch stop
Plasm2: WaitVblank
lea PBmap(a6),a0 ; bit map
move.l sineptr(a6),a4 ; pointer to sine table
lea stripes(pc),a2 ; "stripe data"
move.l a6,d2 ; data seg
add.l #plasma_copper1+6,d2 ; raster data
move.w #ROWS-1,d0 ; loop counter
move.l #$09f00000,d3 ; bltcon0 & bltcon1
moveq #$f,d5 ; mask off upper bits
moveq #64+26,d6 ; blit window
map_top: tst.b (a4) ; is it -1 ($ff)?
bpl.b .no_sine_reset ; nope
lea sine(pc),a4 ; reset sine pointer
.no_sine_reset: WaitBlit ; wait for it...
move.l a0,a3 ; ptr to bit map
; you can replace this with a move.b (a4),d1 and see what happens
moveq #AMP,d1 ; amplitude of sine wave
sub.b (a4),d1 ; less sine value
lsr.w #4,d1 ; divide by 16 (nearest word offset)
add.w d1,d1 ; word offset
add.w d1,a3 ; add to bit map pointer
; if you made above into a move.b (a4),d1 then do it here, too.
moveq #AMP,d1 ; amplitude of sine wave
sub.b (a4),d1 ; less sine value
and.l d5,d1 ; mask off upper bits to make into
; shift value
ror.l #4,d1 ; put shift value in high nibble
or.l d3,d1 ; or into bplcon
; I'm only doing one line at a time, so the modulos
; are irrelevant.
move.l d1,$40-2(a5) ; bltcon0 & bltcon1
move.l #-1,$44-2(a5) ; first word mask
movem.l a2/a3,$50-2(a5) ; source
move.w d6,$58-2(a5) ; blit window
adda.w #54,a0 ; next raster in bit map
lea color_list(pc),a1 ; Get start of color lists.
move.b (a4)+,d1 ; sine value (again!)
add.w d1,d1 ; word align.
add.w d4,a1 ; gives copper a cool 'scrolly' effect
; try removing.
add.w d1,a1 ; new position in color table (sine)
moveq #MOD,d1 ; in the clist, this is how big the
; first part of the 'move' is.
WaitBlit
move.l d3,$40-2(a5) ; bltcon0 & bltcon1
move.l d1,$64-2(a5) ; dest mod.
move.l a1,$50-2(a5) ; source A
move.l d2,$54-2(a5) ; dest.
move.w #SIZE,$58-2(a5) ; bltsize
add.l #MD2,d2 ; Next color in copper list.
dbra d0,map_top ; loop
end_frame: lea sineptr(a6),a1 ; old sine ptr
addq.l #1,(a1) ; next place in sine table
move.l (a1),a1 ; new sine ptr
tst.b (a1) ; is it -1?
bpl.b .no_sine_reset ; no.
lea sine(pc),a4 ; reset sine pointer
move.l a4,sineptr(a6) ; reset sine prt
.no_sine_reset: addq.w #(S_SPEED),d4 ; scroll speed
cmpi.w #(S_SIZE),d4 ; past scroll limit?
blt.b .no_scroll_reset
moveq #0,d4 ; reset copper scrolly value
.no_scroll_reset:
btst.b #6,CIA_A ; is lmb down?
bne.w Plasm2 ; not yet...
move.l a6,a4
movea.l 4.w,a6 ; ExecBase
lea GraphicsName(pc),a1 ; "graphics.library"
jsr -$198(a6) ; OldOpenLibrary()
move.l d0,a1 ; Copy ptr to GfxBase
move.l $26(a1),$80-2(a5) ; Install old system copperlist
jsr -$19e(a6) ; CloseLibrary()
move.l a4,a1
move.w #$7fff,$96-2(a5) ; Kill all DMA!
move.w (a1),$96-2(a5) ; Activate old DMA channels
move.l #(size_of_list),d0 ; size of block
jsr -$d2(a6) ; Free()
err_exit: lea DosName(pc),a1 ; pointer to lib. name
jsr -$60(a6) ; FindResident()
tst.l d0 ; error?
beq.b .error ; yes.
move.l d0,a0 ; ptr to dos base
move.l $16(a0),a0 ; pointer to dos lib
moveq #0,d0 ; return no error
.exit: movem.l (sp)+,d1-d7/a1-a6
rts ; Done
.error: moveq #-1,d0 ; error code
bra.b .exit
***********************************************************
stripes:dc.l $00ff00ff,$ff00ff00,$00ff00ff,$ff00ff00,$00ff00ff,$ff00ff00
dc.l $00ff00ff,$ff00ff00,$00ff00ff,$ff00ff00,$00ff00ff,$ff00ff00
dc.l $00ff00ff
color_list:
dc.l $ff00ff0,$fe10fd2,$fc30fb4,$fa50f96,$f870f78,$f690f5a
dc.l $f4b0f3c,$f2d0f1e,$f0f0f0f,$f0f0f0f,$f1e0f2d,$f3c0f4b
dc.l $f5a0f69,$f780f87,$f960fa5,$fb40fc3,$fd20fe1,$ff00ff0
dc.l $ff00ff0,$fe10fd2,$fc30fb4,$fa50f96,$f870f78,$f690f5a
dc.l $f4b0f3c,$f2d0f1e,$f0f0f0f,$f0f0f0f,$f1e0f2d,$f3c0f4b
dc.l $f5a0f69,$f780f87,$f960fa5,$fb40fc3,$fd20fe1,$ff00ff0
dc.l $ff00ff0,$fe10fd2,$fc30fb4,$fa50f96,$f870f78,$f690f5a
dc.l $f4b0f3c,$f2d0f1e,$f0f0f0f,$f0f0f0f,$f1e0f2d,$f3c0f4b
dc.l $f5a0f69,$f780f87,$f960fa5,$fb40fc3,$fd20fe1,$ff00ff0
dc.l $ff00ff0,$fe10fd2,$fc30fb4,$fa50f96
; Sine table MUST end with a $ff!
sine: dc.l $10111213,$14161718,$191a1b1c,$1c1d1e1e,$1f1f1f1f,$1f1f1f1f
dc.l $1f1e1e1d,$1d1c1b1a,$19181716,$15141311,$10100f0e,$0c0b0a09
dc.l $08070605,$04030302,$02010101,$01010101,$01010202,$03040405
dc.w $0607,$0809,$0a0b,$0d0e,$0fff
GraphicsName: dc.b 'graphics.library',0
DosName: dc.b 'dos.library',0
message: dc.b "Not a virus! A plasma bb by the DF of Epsilon!"
*********************************************************************
rsreset
DMACONSave rs.w 1 ; save DMA bits here
sineptr rs.l 1
PBmap rs.b 54*ROWS+100 ; plasma bit map
Copper1 rs.b 0 ; start of copper list
mapptrs rs.w 16 ; bmap pointer
plasma_copper1 rs.b (4*(ROWS*(1+(COLS*COLORS)))) ; raster data
pe_1 rs.w 2 ; end of clist
size_of_list rs.b 0 ; duh! :^)